#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>


unsigned int bufferBlock[64*1024];
char bufferFiles[256];

void searchFiles(int portnr, char* host, char* pattern) {
    int sockfd, portno, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;

    portno = portnr;

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        close_socket();
        error("ERROR opening socket");
    }
    server = gethostbyname(host);
    if (server == NULL) {
        close_socket();
        fprintf(stderr, "ERROR, no such host\n");
        exit(0);
    }
    bzero((char *) &serv_addr, sizeof (serv_addr));
    serv_addr.sin_family = AF_INET;
    bcopy((char *) server->h_addr,
            (char *) &serv_addr.sin_addr.s_addr,
            server->h_length);
    serv_addr.sin_port = htons(portno);
    if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0)
        error("ERROR connecting");
    char message[50] = "SEARCH ";
    char *messagePointer = message;
    strcat(messagePointer, pattern);
    strcat(messagePointer, "\n");
    n = send(sockfd, messagePointer, strlen(messagePointer), 0);
    if (n < 0) {
        close_socket();
        error("ERROR writing to socket");
    }
    bzero(bufferFiles, 256);
    n = read(sockfd, bufferFiles, 255);
    if (n < 0){
        close_socket();
        error("ERROR reading from socket");
    }
    printf("%s\n", bufferFiles);

    close(sockfd);
}

void getRemoteBlock(int portnr, char* host, char *fn, char* block_nr) {
    int sockfd, portno, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;

    portno = portnr;

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        close_socket();
        error("ERROR opening socket");
    }
    server = gethostbyname(host);
    if (server == NULL) {
        close_socket();
        fprintf(stderr, "ERROR, no such host\n");
        exit(0);
    }
    bzero((char *) &serv_addr, sizeof (serv_addr));
    serv_addr.sin_family = AF_INET;
    bcopy((char *) server->h_addr,
            (char *) &serv_addr.sin_addr.s_addr,
            server->h_length);
    serv_addr.sin_port = htons(portno);
    if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0) {
        close_socket();
        error("ERROR connecting");
    }
    char message[200] = "GET ";
    char *messagePointer = message;
    strcat(messagePointer, fn);
    strcat(messagePointer, " ");
    strcat(messagePointer, block_nr);
    strcat(messagePointer, "\n");
    n = send(sockfd, messagePointer, strlen(messagePointer), 0);
    if (n < 0) {
        close_socket();
        error("ERROR writing to socket");
    
    }
    bzero(bufferFiles, 256);
    bzero(bufferBlock, (sizeof(bufferBlock))/(sizeof bufferBlock[0]));
    n = recv(sockfd, bufferBlock, (sizeof(bufferBlock))/(sizeof(bufferBlock[0])), MSG_WAITALL);
    if (n < 0) {
        close_socket();
        error("ERROR reading from socket");
    }
    printf("%d\n", n);
    close(sockfd);
    if(n== (64*1024)){
    sendToStorageServer(9002, "192.168.1.212", fn, block_nr);
    }
}

void sendToStorageServer(int portnr, char* host, char* fn, char* block_nr) {
    int sockfd, portno, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;

    portno = portnr;

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        close_socket();
        error("ERROR opening socket");       
    }
    server = gethostbyname(host);
    if (server == NULL) {
        fprintf(stderr, "ERROR, no such host\n");
        close_socket();
        exit(0);
    }
    bzero((char *) &serv_addr, sizeof (serv_addr));
    serv_addr.sin_family = AF_INET;
    bcopy((char *) server->h_addr,
            (char *) &serv_addr.sin_addr.s_addr,
            server->h_length);
    serv_addr.sin_port = htons(portno);
    if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) < 0) {
        close_socket();
        error("ERROR connecting");
    }

    char message[200] = "POST ";
    char *messagePointer = message;
    strcat(messagePointer, fn);
    strcat(messagePointer, ".block");
    strcat(messagePointer, block_nr);
    strcat(messagePointer, "\n");
    n = send(sockfd, messagePointer, strlen(messagePointer), MSG_NOSIGNAL);
    if (n < 0) {
        close_socket();
        error("ERROR writing to socket");
    }
    bzero(bufferFiles, 256);
    n = read(sockfd, bufferFiles, 256);
    if (n < 0) 
        error("ERROR reading from socket");
    printf("%s\n", bufferFiles);
    if (0 <= strcmp(bufferFiles, "OK")) {
        n = send(sockfd, bufferBlock, (sizeof(bufferBlock))/(sizeof bufferBlock[0]), MSG_WAITALL);
       // printf("%s\n", bufferBlock);
        bzero(bufferBlock, (sizeof(bufferBlock))/(sizeof bufferBlock[0]));
        if (n < 0) {
            close_socket();
            error("ERROR writing to socket");
        }
        printf("Sent file.\n");
    }

    //close(sockfd);
}